2026-01-16 13:03:16 +04:00
// EIA (Energy Information Administration) API proxy
// Keeps API key server-side
2026-02-15 20:33:20 +04:00
import { getCorsHeaders , isDisallowedOrigin } from '../_cors.js' ;
2026-01-16 13:03:16 +04:00
export const config = { runtime : 'edge' } ;
export default async function handler ( req ) {
2026-02-15 20:33:20 +04:00
const cors = getCorsHeaders ( req ) ;
if ( isDisallowedOrigin ( req ) ) {
return new Response ( JSON . stringify ( { error : 'Origin not allowed' } ) , { status : 403 , headers : cors } ) ;
}
2026-01-16 16:18:41 +04:00
// Only allow GET and OPTIONS methods
2026-02-15 20:33:20 +04:00
if ( req . method === 'OPTIONS' ) {
return new Response ( null , { status : 204 , headers : cors } ) ;
}
if ( req . method !== 'GET' ) {
2026-01-16 16:18:41 +04:00
return Response . json ( { error : 'Method not allowed' } , {
status : 405 ,
2026-02-15 20:33:20 +04:00
headers : cors ,
2026-01-16 16:18:41 +04:00
} ) ;
}
2026-01-16 13:03:16 +04:00
const url = new URL ( req . url ) ;
const path = url . pathname . replace ( '/api/eia' , '' ) ;
const apiKey = process . env . EIA _API _KEY ;
if ( ! apiKey ) {
return Response . json ( {
configured : false ,
2026-02-14 19:52:57 +04:00
skipped : true ,
reason : 'EIA_API_KEY not configured' ,
2026-01-16 13:03:16 +04:00
} , {
2026-02-14 19:52:57 +04:00
status : 200 ,
2026-02-15 20:33:20 +04:00
headers : cors ,
2026-01-16 13:03:16 +04:00
} ) ;
}
// Health check
if ( path === '/health' || path === '' ) {
return Response . json ( { configured : true } , {
2026-02-15 20:33:20 +04:00
headers : cors ,
2026-01-16 13:03:16 +04:00
} ) ;
}
// Petroleum data endpoint
if ( path === '/petroleum' ) {
try {
const series = {
wti : 'PET.RWTC.W' ,
brent : 'PET.RBRTE.W' ,
production : 'PET.WCRFPUS2.W' ,
inventory : 'PET.WCESTUS1.W' ,
} ;
const results = { } ;
// Fetch all series in parallel
const fetchPromises = Object . entries ( series ) . map ( async ( [ key , seriesId ] ) => {
try {
const response = await fetch (
` https://api.eia.gov/v2/seriesid/ ${ seriesId } ?api_key= ${ apiKey } &num=2 ` ,
{ headers : { 'Accept' : 'application/json' } }
) ;
if ( ! response . ok ) return null ;
const data = await response . json ( ) ;
const values = data ? . response ? . data || [ ] ;
if ( values . length >= 1 ) {
return {
key ,
data : {
current : values [ 0 ] ? . value ,
previous : values [ 1 ] ? . value || values [ 0 ] ? . value ,
date : values [ 0 ] ? . period ,
unit : values [ 0 ] ? . unit ,
}
} ;
}
} catch ( e ) {
console . error ( ` [EIA] Failed to fetch ${ key } : ` , e . message ) ;
}
return null ;
} ) ;
const fetchResults = await Promise . all ( fetchPromises ) ;
for ( const result of fetchResults ) {
if ( result ) {
results [ result . key ] = result . data ;
}
}
return Response . json ( results , {
headers : {
2026-02-15 20:33:20 +04:00
... cors ,
'Cache-Control' : 'public, max-age=1800, s-maxage=1800, stale-while-revalidate=300' ,
2026-01-16 13:03:16 +04:00
} ,
} ) ;
} catch ( error ) {
2026-01-16 16:18:41 +04:00
console . error ( '[EIA] Fetch error:' , error ) ;
2026-01-16 13:03:16 +04:00
return Response . json ( {
2026-01-16 16:18:41 +04:00
error : 'Failed to fetch EIA data' ,
2026-01-16 13:03:16 +04:00
} , {
status : 500 ,
2026-02-15 20:33:20 +04:00
headers : cors ,
2026-01-16 13:03:16 +04:00
} ) ;
}
}
return Response . json ( { error : 'Not found' } , {
status : 404 ,
2026-02-15 20:33:20 +04:00
headers : cors ,
2026-01-16 13:03:16 +04:00
} ) ;
}